#include <ctime>

#include "metrics/Gauge.hpp"
#include "metrics/Builder.hpp"

namespace metrics
{
    Gauge::Gauge(double v) : _value{v}
    {
    }

    Gauge::~Gauge()
    {
    }

    void Gauge::increment(double value)
    {
        change(value);
    }

    void Gauge::decrement(double value)
    {
        change(-1.0 * value);
    }

    void Gauge::set(double v)
    {
        _value.store(v);
    }

    void Gauge::set_current_time()
    {
        const auto time = std::time(nullptr);
        set(static_cast<double>(time));
    }

    double Gauge::value() const { return _value; }

    ClientMetric Gauge::collect() const
    {
        ClientMetric metric;
        metric.gauge.value = value();
        return metric;
    }

    void Gauge::change(double value)
    {
        double old = 0;
        do
        {
            old = _value.load();
        } while (!_value.compare_exchange_weak(old, old + value));
    }

    Builder<Gauge> BuildGauge() { return {}; }

} // namespace metrics